home *** CD-ROM | disk | FTP | other *** search
- **********************************************************************
- *
- * $RCSfile: Mark.asm $
- * Description: Runtime support for the Oberon-A compiler
- *
- * Created by: fjc (Frank Copeland)
- * $Revision: 1.2 $
- * $Author: fjc $
- * $Date: 1995/01/26 00:37:31 $
- *
- * Copyright © 1994, Frank Copeland.
- * This file is part of the Oberon-A Library.
- * See Oberon-A.doc for conditions of use and distribution.
- *
- * Log entries are at the end of the file.
- *
- **********************************************************************
-
- ;---------------------------------------------------------------------
- ; Program unit hunk name
- ; !! DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING !!
-
- TTL Kernel
-
- ;---------------------------------------------------------------------
- ; Defines
-
- SysBit EQU 0
- ArrayBit EQU 1
- MarkBitB EQU 7
- MarkBitL EQU 31
- tag EQU -4
- size EQU -12
- elemSize EQU -16
- arrpos EQU -20
- PtrTabOffset EQU 36
-
-
- ;---------------------------------------------------------------------
- ;
- ; PROCEDURE Kernel_Mark (q {A0} : Pointer)
- ;
- ; Kernel_Mark is a direct implementation of the algorithm described in
- ; the Oberon Technical Notes, part 5 (see TechNotes.doc). It forms
- ; the inner loop of the mark phase and assumes that the root pointer
- ; variable passed in A0 has already been marked. The algorithm has
- ; been modified slightly to reflect the different tag encodings and
- ; memory block formats used by Oberon-A.
- ;
- ; Address registers A1-A3 and all the data registers are free on
- ; entry.
- ;
- ; VAR
- ; n {A1}, t {A2}, tos {A3} : Pointer;
- ; offset {D0}, tag {A4,D3} : LONGINT;
- ; qmask {D1}, ntag {D2} : SET;
- ;
- ;---------------------------------------------------------------------
-
- SECTION OberonSys,CODE
-
- XDEF Kernel_Mark
-
- Kernel_Mark:
-
- MOVE.L A4,-(A7) ; (* Create an extra free register *)
- BTST.B #ArrayBit,tag+3(A0) ; IF 1 IN q.tag THEN
- BEQ.S M1
- CLR.L arrpos(A0) ; q.arrpos := 0;
- MOVE.L #$80000002,D1 ; qmask := {1, 31}
- BRA.S M2
- M1: ; ELSE
- MOVE.L #$80000000,D1 ; qmask := {31}
- M2: ; END;
- MOVE.L A0,A2 ; t := q;
- MOVE.L tag(A0),D3 ; tag := q.tag - {1, 31} + PtrTabOffset
- AND.L #$7FFFFFFD,D3
- ADD.L #PtrTabOffset,D3
- SUB.L A3,A3 ; tos := NIL;
- Loop: ; LOOP {H}
- MOVE.L D3,A4 ; offset := mem[tag];
- MOVE.L (A4),D0
- BPL.S L3 ; IF offset < 0 THEN
- MOVE.L D3,D4 ; q.tag := tag + offset + qmask;
- ADD.L D0,D4
- OR.L D1,D4
- MOVE.L D4,tag(A0)
- BTST.B #ArrayBit,D1 ; IF 1 IN qmask
- BEQ.S L1
- MOVE.L elemSize(A0),D4
- ADD.L arrpos(A0),D4
- CMP.L size(A0),D4 ; & (q.arrpos + q.elemSize # q.size) THEN
- BEQ.S L1
- MOVE.L elemSize(A0),D4 ; INC(q.arrpos,q.elemSize);
- ADD.L D4,arrpos(A0)
- ADD.L D0,D3 ; INC(tag, offset + PtrTabOffset - 4);
- ADD.L #PtrTabOffset-4,D3
- ADD.L elemSize(A0),A2 ; INC(t, q.elemSize)
- BRA L5
- L1:
- MOVE.L A3,D4 ; ELSIF tos = NIL THEN
- BEQ Exit ; EXIT
- ; ELSE
- MOVE.L tag(A3),D1 ; qmask := tos.tag;
- MOVE.L D1,D3 ; tag := qmask - {1, 31};
- AND.L #$7FFFFFFD,D3
- AND.L #$80000002,D1 ; qmask := qmask * {1, 31};
- MOVE.L A3,A2 ; t := tos;
- BTST.B #ArrayBit,D1 ; IF 1 IN qmask THEN
- BEQ.S L2
- ADD.L arrpos(A3),A2 ; INC (t, tos.arrpos)
- L2: ; END;
- MOVE.L D3,A4 ; offset := mem[tag];
- MOVE.L (A4),D0
- MOVE.L 0(A2,D0.L),A1 ; n := mem[t + offset];
- MOVE.L A0,0(A2,D0.L) ; mem[t + offset] := q;
- MOVE.L A3,A0 ; q := tos;
- MOVE.L A1,A3 ; tos := n
- BRA.S L5 ; END
- L3: ; ELSE
- MOVE.L 0(A2,D0.L),D4 ; n := mem[t + offset];
- BEQ.S L5 ; IF (n # NIL) THEN
- MOVE.L D4,A1
- MOVE.L tag(A1),D2 ; ntag := n.tag;
- BTST.L #MarkBitL,D2 ; IF ~(31 IN ntag) [Unmarked]
- BNE.S L5
- ; MOVE.L D2,D4 ; n.tag := ntag + {31};
- ; BSET.L #MarkBitL,D4
- ; MOVE.L D4,tag(A1)
- BSET.B #MarkBitB,tag(A1) ; n.tag := n.tag + {31};
- BTST.L #SysBit,D2 ; IF ~(0 IN ntag) THEN [~SysBlk]
- BNE.S L5
- MOVE.L D3,tag(A0) ; q.tag := tag + qmask;
- OR.L D1,tag(A0)
- BTST.B #ArrayBit,D2 ; IF ~(1 IN ntag) THEN
- BNE.S L4
- MOVE.L A3,0(A2,D0.L) ; mem[t + offset] := tos;
- MOVE.L A0,A3 ; tos := q;
- MOVE.L A1,A0 ; q := n;
- MOVE.L A0,A2 ; t := q;
- MOVE.L D2,D3 ; tag := ntag + PtrTabOffset - 4;
- ADD.L #PtrTabOffset-4,D3
- MOVE.L #$80000000,D1 ; qmask := {31}
- BRA.S L5
- L4:
- BTST.B #SysBit,D2 ; ELSIF ~(0 IN ntag) THEN
- BNE.S L5
- MOVE.L A3,0(A2,D0.L) ; mem[t + offset] := tos;
- MOVE.L A0,A3 ; tos := q;
- MOVE.L A1,A0 ; q := n;
- CLR.L arrpos(A0) ; q.arrpos := 0;
- MOVE.L A0,A2 ; t := q;
- MOVE.L D2,D3 ; tag := ntag - {1} + PtrTabOffset - 4;
- BCLR.B #ArrayBit,D3
- ADD.L #PtrTabOffset-4,D3
- MOVE.L #$80000002,D1 ; qmask := {1, 31}
- ; END (* ELSIF *)
- ; END
- ; END (* IF *)
- ; END (* IF *)
- L5: ; END; (* ELSE *)
- ADDQ.L #4,D3 ; INC(tag, 4)
- BRA Loop ; END (* LOOP *)
- Exit:
- MOVE.L (A7)+,A4 ; (* restore A4 *)
- RTS
-
- ;---------------------------------------------------------------------
-
- END ; Kernel
-
- **********************************************************************
- *
- * $Log: Mark.asm $
- ;; Revision 1.2 1995/01/26 00:37:31 fjc
- ;; - Release 1.5
- ;;
- **********************************************************************
-